import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:boxes_flutter/flutter/slc/dialog/dialog_loading_vm.dart';
import 'package:boxes_flutter/flutter/slc/mvvm/base_mvvm.dart';
import 'package:boxes_flutter/flutter/slc/mvvm/status_widget.dart';
import 'package:boxes_flutter/flutter/slc/router/router_vm.dart';
import 'package:boxes_flutter/flutter/slc/router/slc_router.dart';

/// @author: slc
/// 快速无状态组件类，继承自 MvvmStatelessWidget 并混入 StatusWidget
///
/// [T] 继承自 FastVm 的类型参数
abstract class FastStatelessWidget<T extends FastVm> extends MvvmStatelessWidget<T>
    with StatusWidget<T> {
  late final LoadingDialogWidgetVd loadingDialogWidgetVd;

  late final RouterWidgetVd routerWidgetVd;

  /// 构造函数，接收可选的 LoadingDialogWidgetVd 和 RouterWidgetVd 参数
  ///
  /// [loadingDialogWidgetVd] 可选的 LoadingDialogWidgetVd 实例
  /// [routerWidgetVd] 可选的 RouterWidgetVd 实例
  FastStatelessWidget(
      {super.key, LoadingDialogWidgetVd? loadingDialogWidgetVd, RouterWidgetVd? routerWidgetVd}) {
    this.loadingDialogWidgetVd = loadingDialogWidgetVd ?? LoadingDialogWidgetVd();
    this.routerWidgetVd = routerWidgetVd ?? RouterWidgetVd();
  }

  /// 注册事件
  ///
  /// [context] 上下文对象
  /// [listen] 是否监听数据变化，默认为 false
  /// 此方法相较于父类新增了注册 LoadingDialogWidgetVd 和 RouterWidgetVd 的逻辑
  @override
  void registerEvent(BuildContext context, {listen = false}) {
    super.registerEvent(context, listen: listen);
    loadingDialogWidgetVd.registerDialogEvent(context, getVm().loadingDialogVmSub);
    routerWidgetVd.registerRouterEvent(context, getVm().routerVmSub);
    routerWidgetVd.onResult = onResult;
  }

  /// 处理结果
  ///
  /// [requestCode] 请求码
  /// [result] 结果数据
  onResult(int requestCode, dynamic result) {}
}

/// 快速状态类，继承自 MvvmState 并混入 StatusWidget
///
/// [W] 继承自 StatefulWidget 的类型参数
/// [T] 继承自 FastVm 的类型参数
abstract class FastState<W extends StatefulWidget, T extends FastVm> extends MvvmState<W, T>
    with StatusWidget<T> {
  late final LoadingDialogWidgetVd loadingDialogWidgetVd;

  late final RouterWidgetVd routerWidgetVd;

  /// 构造函数，接收可选的 LoadingDialogWidgetVd 和 RouterWidgetVd 参数
  ///
  /// [loadingDialogWidgetVd] 可选的 LoadingDialogWidgetVd 实例
  /// [routerWidgetVd] 可选的 RouterWidgetVd 实例
  FastState({LoadingDialogWidgetVd? loadingDialogWidgetVd, RouterWidgetVd? routerWidgetVd}) {
    this.loadingDialogWidgetVd = loadingDialogWidgetVd ?? LoadingDialogWidgetVd();
    this.routerWidgetVd = routerWidgetVd ?? RouterWidgetVd();
  }

  /// 注册事件
  ///
  /// [context] 上下文对象
  /// [listen] 是否监听数据变化，默认为 false
  @override
  void registerEvent(BuildContext context, {listen = false}) {
    super.registerEvent(context, listen: listen);
    loadingDialogWidgetVd.registerDialogEvent(context, getVm().loadingDialogVmSub);
    routerWidgetVd.registerRouterEvent(context, getVm().routerVmSub);
    routerWidgetVd.onResult = onResult;
  }

  @override
  void dispose() {
    super.dispose();
  }

  /// 处理结果
  ///
  /// [requestCode] 请求码
  /// [result] 结果数据
  void onResult(int requestCode, dynamic result) {}
}

/// 快速 ViewModel 类，继承自 BaseVm 并实现多个接口，使Vm拥有Loading、路由、页面状态的能力
class FastVm extends BaseVm implements ILoadingDialogVmSub, IRouterVmSub, IStatusVm {
  final LoadingDialogVmSub loadingDialogVmSub = LoadingDialogVmSub();
  final RouterVmSub routerVmSub = RouterVmSub();
  final StatusVm statusVm = StatusVm();

  @override
  dismissLoading() {
    loadingDialogVmSub.dismissLoading();
  }

  @override
  showLoading({String? text}) {
    return loadingDialogVmSub.showLoading(text: text);
  }

  @override
  finish({result}) {
    routerVmSub.finish(result: result);
  }

  @override
  Future pushNamed(String routeName,
      {Map<String, dynamic> arguments = const <String, dynamic>{},
      Object? extra,
      int requestCode = 0}) {
    return routerVmSub.pushNamed(routeName,
        arguments: arguments, extra: extra, requestCode: requestCode);
  }

  @override
  Future pushNamedInfo(SlcRouterInfo slcRouterInfo) {
    return routerVmSub.pushNamedInfo(slcRouterInfo);
  }

  @override
  Future pushPage(Widget page, {RouteSettings? routeSettings, int requestCode = 0}) {
    return routerVmSub.pushPage(page, routeSettings: routeSettings, requestCode: requestCode);
  }

  @override
  Future pushPageParams(PushPageParams startPageParams) {
    return routerVmSub.pushPageParams(startPageParams);
  }

  @override
  Future pushReplacementNamed(String routeName,
      {Map<String, dynamic> arguments = const <String, dynamic>{},
      Object? extra,
      int requestCode = 0}) {
    return routerVmSub.pushReplacementNamed(routeName,
        arguments: arguments, extra: extra, requestCode: requestCode);
  }

  @override
  Future pushReplacementNamedInfo(SlcRouterInfo slcRouterInfo) {
    return routerVmSub.pushReplacementNamedInfo(slcRouterInfo);
  }

  @override
  Future pushReplacementPage(Widget page, {RouteSettings? routeSettings, int requestCode = 0}) {
    return routerVmSub.pushReplacementPage(page,
        routeSettings: routeSettings, requestCode: requestCode);
  }

  @override
  Future pushReplacementPageParams(PushPageParams startPageParams) {
    return routerVmSub.pushReplacementPageParams(startPageParams);
  }

  @override
  void setLoadingStatus(LoadingStatus status) {
    setLoadingStatusWithNotify(status, notify: true);
  }

  void setLoadingStatusWithNotify(LoadingStatus status, {bool notify = true}) {
    bool isNotifyListeners = getLoadingStatus() != status;
    statusVm.setLoadingStatus(status);
    if (isNotifyListeners && notify) {
      notifyListeners();
    }
  }

  @override
  LoadingStatus getLoadingStatus() {
    return statusVm.getLoadingStatus();
  }
}

/// 快速 VmSub 类，继承自 VmSub 并实现多个接口，使VmSub拥有Loading、路由、页面状态的能力，这些能力由Vm提供
class FastVmSub extends VmSub implements ILoadingDialogVmSub, IRouterVmSub, IStatusVm {
  VmSub() {}

  /// 获取 FastVm 实例
  ///
  /// @return FastVm 实例
  /// @throws Exception 如果所有者 ViewModel 不是 FastVm
  FastVm getFastVm() {
    BaseVm ownerVm = getOwnerVm();
    if (ownerVm is FastVm) {
      return ownerVm;
    }
    throw Exception("ownerVm 不是 FastVm");
  }

  @override
  dismissLoading() {
    getFastVm().dismissLoading();
  }

  @override
  showLoading({String? text}) {
    return getFastVm().showLoading(text: text);
  }

  @override
  finish({result}) {
    getFastVm().finish(result: result);
  }

  @override
  Future pushNamed(String routeName,
      {Map<String, dynamic> arguments = const <String, dynamic>{},
      Object? extra,
      int requestCode = 0}) {
    return getFastVm()
        .pushNamed(routeName, arguments: arguments, extra: extra, requestCode: requestCode);
  }

  @override
  Future pushNamedInfo(SlcRouterInfo slcRouterInfo) {
    return getFastVm().pushNamedInfo(slcRouterInfo);
  }

  @override
  Future pushPage(Widget page, {RouteSettings? routeSettings, int requestCode = 0}) {
    return getFastVm().pushPage(page, routeSettings: routeSettings, requestCode: requestCode);
  }

  @override
  Future pushPageParams(PushPageParams startPageParams) {
    return getFastVm().pushPageParams(startPageParams);
  }

  @override
  Future pushReplacementNamed(String routeName,
      {Map<String, dynamic> arguments = const <String, dynamic>{},
      Object? extra,
      int requestCode = 0}) {
    return getFastVm().pushReplacementNamed(routeName,
        arguments: arguments, extra: extra, requestCode: requestCode);
  }

  @override
  Future pushReplacementNamedInfo(SlcRouterInfo slcRouterInfo) {
    return getFastVm().pushReplacementNamedInfo(slcRouterInfo);
  }

  @override
  Future pushReplacementPage(Widget page, {RouteSettings? routeSettings, int requestCode = 0}) {
    return getFastVm()
        .pushReplacementPage(page, routeSettings: routeSettings, requestCode: requestCode);
  }

  @override
  Future pushReplacementPageParams(PushPageParams startPageParams) {
    return getFastVm().pushReplacementPageParams(startPageParams);
  }

  @override
  setLoadingStatus(LoadingStatus status) {
    getFastVm().setLoadingStatus(status);
  }

  @override
  LoadingStatus getLoadingStatus() {
    return getFastVm().getLoadingStatus();
  }
}
